import http from 'http'
import https from 'https'
import fs from 'fs'
import path from 'path'
import mime from 'mime'
import { TokenData, parse, compile, match, pathToRegexp, stringify } from 'path-to-regexp'
/* 
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
 */
const isHttps = true
const protocol = isHttps ? 'https' : 'http'
export default class CreateServer {
  constructor(config = { port: isHttps ? 443 : 80 }) {
    this.https = https
    this.http = http
    this.server = this[protocol].createServer({
      key: fs.readFileSync(path.join(process.cwd(), '/ssl/server.key'), 'utf-8').toString(),
      cert: fs.readFileSync(path.join(process.cwd(), '/ssl/server.cert'), 'utf-8').toString()

    }, this.serverCallback.bind(this)/* (req,res)=>{
      console.log(req)
      res.end('ok')
    } */)
    this.server.listen(config.port, function (err) {
      console.log(err)
      console.log(`服务器启动成功，可以通过"${protocol}://127.0.0.1:${config.port}/"来进行访问`);
    });
    this.staticRouters = {}
    this.postRouters = {}
    this.getRouters = {}
  }
  async serverCallback(req, res) {
    res.setHeader('Access-Control-Allow-Origin', '*')
    const urlObj = new URL(req.url, `${protocol}://${req.headers.host}/`)
    const query = {};
    for (const [key, value] of urlObj.searchParams) {
      query[key] = value;
    }
    req.query = query
    if (!this.inAllRouters(urlObj)) return
    if (this.dealStaticReq(urlObj, res)) return
    if (this.dealGetReq(urlObj, req, res)) return
    res.writeHead(404, { 'Content-Type': 'text/plain;charset=utf-8' })
    res.end('该地址不存在');
  }
  dealStaticReq({ pathname }, res) {
    let isMatch = false
    for (let key in this.staticRouters) {
      let filePath = path.join(process.cwd(), key, pathname)
      if (!isMatch && fs.existsSync(filePath)) {
        try {
          const stats = fs.statSync(filePath)
          if (stats.isDirectory()) filePath += '/index.html'
          res.setHeader('Content-Type', mime.getType(filePath) + ';charset=utf-8');
          fs.accessSync(filePath, fs.constants.R_OK)
          fs.createReadStream(filePath).pipe(res)
          isMatch = true
        } catch (e) {
        }
      }
    }
    return isMatch
  }
  dealGetReq(urlObj, req, res) {
    let isMatch = false
    Object.keys(this.getRouters).map(api => {
      const matchApi = api.slice(0, api.includes(":") ? api.indexOf(":") - 1 : api.length)
      if (urlObj.pathname.includes(matchApi)) {
        if (api.includes(":")) {
          const params = match(api)(urlObj.pathname).params
          req.params = params
        }
        this.getRouters[api](req, res)
        isMatch = true
      }
    })
    return isMatch
  }
  post(path, callback) {
    this.postRouters[path] = callback
  }
  get(path, callback) {
    this.getRouters[path] = callback
  }
  static(path, callback) {
    this.staticRouters[path] = callback
  }

  inAllRouters(urlObj) {
    return Object.keys({ ...this.staticRouters, ...this.getRouters, ...this.postRouters }).map(api => api.slice(0, api.includes(":") ? api.indexOf(":") - 1 : api.length)).some(api => {
      return urlObj.pathname.includes(api)
    })
  }
}
